import logging
import time

import requests
from django.contrib.postgres.fields import ArrayField
from django.db import models
from tools.mqtt.push import push_message
# Create your models here.

logger = logging.getLogger(__name__)


class UserDemand(models.Model):
    """用户需求标签"""
    user = models.ForeignKey(
        'zmad.ZTPUser',
        to_field='username',
        db_column='username',
        on_delete=models.CASCADE,
        db_constraint=False,  # Django不会实际添加ON DELETE CASCADE到外键约束，我们需要手动创建
        related_name='demands'
    )
    app_tag = models.CharField(max_length=20)
    demand = models.CharField(max_length=20, null=True)

    class Meta:
        unique_together = [('user', 'app_tag')]


class DailySummary(models.Model):
    """每日活跃情况统计"""
    date = models.DateField(unique=True)        # 日期
    total = models.PositiveIntegerField()       # 总用户数
    active = models.PositiveIntegerField()      # 活跃用户数
    inactive = models.PositiveIntegerField()    # 非活跃用户数
    abnormal = models.PositiveIntegerField()    # 行为异常用户数


class ActivityStatus(models.Model):
    """用户活跃状态监控"""
    user = models.OneToOneField(
        'zmad.ZTPUser',
        on_delete=models.CASCADE,
        db_constraint=False,  # Django不会实际添加ON DELETE CASCADE到外键约束，我们需要手动创建
        related_name='activity_status',
        to_field='username',
        db_column='username',
    )
    is_active = models.BooleanField(default=False)      # 是否活跃
    is_abnormal = models.BooleanField(default=False)    # 是否异常
    update_time = models.DateTimeField(auto_now=True)   # 更新时间


class UserSafetyScore(models.Model):
    """用户信誉评分记录，为具体的扣分详情"""
    user = models.ForeignKey(
        'zmad.ZTPUser',
        to_field='username',
        db_column='username',
        on_delete=models.CASCADE,
        db_constraint=False,  # Django不会实际添加ON DELETE CASCADE到外键约束，我们需要手动创建
        related_name='score'
    )
    user_profile = models.IntegerField(default=0)  # 用户画像扣分
    behaviour_preference = models.IntegerField(default=0)  # 行为偏好扣分
    terminal_security = models.IntegerField(default=0)  # 终端安全扣分
    user_relationship = models.IntegerField(default=0)  # 用户关系扣分
    safety_consciousness = models.IntegerField(default=80)  # 安全意识得分，是得分！
    datetime = models.DateTimeField(auto_now=True)  # 评估日期
    total = models.IntegerField(default=0)          # 总扣分


class UserCreditScoreDetails(models.Model):
    """用户信誉评分记录，为具体的扣分，加分详情，相关评分项有变动则进行记录，以天为时间单位
    """
    user = models.ForeignKey(
        'zmad.ZTPUser',
        to_field='username',
        db_column='username',
        on_delete=models.CASCADE,
        db_constraint=False,  # Django不会实际添加ON DELETE CASCADE到外键约束，我们需要手动创建
        related_name='credit_score'
    )

    terminal_threat = models.IntegerField(default=0)            # 终端威胁扣分
    access_resources = models.IntegerField(default=0)           # 访问资源扣分
    env_baseline = models.IntegerField(default=0)               # 环境基线扣分
    behavior_preference = models.IntegerField(default=0)        # 行为偏好扣分
    access_devices = models.IntegerField(default=0)             # 访问设备扣分
    bonus_point = models.IntegerField(default=1)                # 用户加分
    datetime = models.DateTimeField(auto_now=True)              # 评估日期
    level = models.IntegerField(default=0)                      # 评估时对应风险等级
    credit_score = models.IntegerField(default=400)             # 用户信誉分

    class Meta:
        db_table = '"ztp"."userdata_usercreditscoredetails"'


class UserCreditScore(models.Model):
    """存储用户最新的总得分和对应情况"""
    credit_score = models.IntegerField(default=400)    # 用户的安全信誉分，默认为1000，每次更新用户分的时候会更新一遍该值
    terminal_score = models.IntegerField(default=80)            # 终端威胁扣分
    resources_score = models.IntegerField(default=80)           # 访问资源扣分
    env_score = models.IntegerField(default=80)               # 环境基线扣分
    behavior_score = models.IntegerField(default=80)        # 行为偏好扣分
    devices_score = models.IntegerField(default=80)             # 访问设备扣分
    score_detail = models.CharField(max_length=1000, null=True, default="")
    user = models.OneToOneField(
        'zmad.ZTPUser',
        to_field='username',
        db_column='username',
        on_delete=models.CASCADE,
        db_constraint=False,
        related_name='user_credit_score'
    )

    class Meta:
        db_table = '"ztp"."userdata_usercreditscore"'


class UserAddScore(models.Model):
    """用户信誉评分记录，为具体的加分详情"""
    user = models.ForeignKey(
        'zmad.ZTPUser',
        to_field='username',
        db_column='username',
        on_delete=models.CASCADE,
        db_constraint=False,  # Django不会实际添加ON DELETE CASCADE到外键约束，我们需要手动创建
        related_name='consciousness'
    )
    uninstall_app = models.SmallIntegerField(default=0)     # 卸载恶意软件加分
    scan_code = models.SmallIntegerField(default=0)         # 扫码加分
    fingerprint_login = models.SmallIntegerField(default=0)  # 指纹登录加分
    datetime = models.DateTimeField(auto_now=True)          # 评估日期
    total = models.SmallIntegerField(default=0)             # 总加分


class UserScore(models.Model):
    """存储用户最新的总得分和对应情况"""
    safety_score = models.IntegerField(default=400)    # 用户的安全信誉分，默认为1000，每次更新用户分的时候会更新一遍该值
    score_detail = models.CharField(max_length=1000, null=True, default="")
    user = models.OneToOneField(
        'zmad.ZTPUser',
        to_field='username',
        db_column='username',
        on_delete=models.CASCADE,
        db_constraint=False,
        related_name='user_score'
    )


class Device(models.Model):
    """
    设备表  需要获取的字段 ('id', 'device_type', 'device_type_str', 'device_uuid', 'model', 'os_version', 'strategy')
    """
    user_id = models.IntegerField()
    # id = models.IntegerField()
    device_type = models.IntegerField()
    platform = models.IntegerField()
    device_type_str = models.CharField(max_length=256)
    device_uuid = models.CharField(unique=True, max_length=256)
    model = models.CharField(max_length=256)
    os_version = models.CharField(max_length=256)
    risk_list = ArrayField(models.CharField(max_length=64), default=[], null=True, blank=True)
    online = models.BooleanField(default=True, null=True)  # 是否在线
    last_user_id = models.IntegerField()

    # strategy = models.TextField(blank=True)

    class Meta:
        managed = False
        db_table = '"zmad"."device"'

    def offline(self, username='', body='', level=0, title=''):
        if self.online:
            logger.info('推送消息到 %s' % self.device_uuid)
            push_message(channel=self.device_uuid, body=body, level=level, username=username, title=title)
            # 休息下, 等消息推送到端再关闭防火墙规则
            time.sleep(1)
        # 下线指定uuid设备.
        logger.info('下线指定设备 %s' % self.device_uuid)
        body = {"username": username, "device_uuid": self.device_uuid}
        response = requests.post("http://localhost:38443/cas/inner/offline_device", json=body)
        if not response.json().get("code"):
            return True
        logger.info('未成功下线设备 %s, 响应返回为 %s' % (self.device_uuid, response.json()))
        return False


class Group(models.Model):
    """
    用户属组
    """
    name = models.CharField(max_length=100)

    class Meta:
        managed = False
        db_table = '"zmad"."app_user_ztpgroup"'


class User(models.Model):
    """
    用户表，关联用户id和用户名
    """
    # id = models.IntegerField()
    username = models.CharField(unique=True, max_length=256)

    class Meta:
        managed = False
        db_table = '"zmad"."app_user_ztpuser"'
